/* q3a_thread.h
 *
 * Copyright (c) 2013 Qualcomm Technologies, Inc. All Rights Reserved.
 * Qualcomm Technologies Proprietary and Confidential.
 */

#ifndef __Q3A_THREAD_H__
#define __Q3A_THREAD_H__

#include <pthread.h>
#include <semaphore.h>
#include "aec_module.h"
#include "awb_module.h"
#include "af_module.h"


/** q3a_thread_type_t
 *
 *  This enumeration represents the types of threads in the Q3A thread module.
 **/
typedef enum {
  Q3A_THREAD_AECAWB,
  Q3A_THREAD_AF,

  Q3A_THREAD_NONE
} q3a_thread_type_t;

/** q3a_thread_data_t
 *    @msg_q_lock:   Mutex lock for protecting concurrent access to the message
 *                   queue
 *    @msg_q:        The main message queue contains all the messages coming
 *                   to the port
 *    @p_msg_q:      The same as the main message queue, but messages in this
 *                   queue will be processed before those in the normal queue
 *    @active:       A flag indicating if the thread is active or not. If the
 *                   flag is FALSE, the queue will refuse to accept new messages
 *    @thread_cond:  Conditional variable to wake the thread when new message
 *                   arrives in the queue
 *    @thread_mutex: Mutex to lock the conditional variable - needed for the
 *                   signaling mechanism
 *    @thread_id:    The ID of the thread when created. Needed by the join
 *                   operation when the thread exits
 *
 *  This structure is used for creating the thread handlers that will process
 *  the messages in the queues and take appropriate actions by calling the
 *  libraries and the callbacks.
 **/
typedef struct {
  pthread_mutex_t msg_q_lock;
  mct_queue_t     *msg_q;
  mct_queue_t     *p_msg_q;
  boolean         active;
  pthread_cond_t  thread_cond;
  pthread_mutex_t thread_mutex;
  pthread_t       thread_id;
  sem_t           sem_launch; /* semaphore to sync thread create */
  uint8_t         aec_bg_stats_cnt;
  uint8_t         awb_bg_stats_cnt;
} q3a_thread_data_t;

/** q3a_thread_aecawb_data_t
 *    @thread_data: Contains the thread data associated with the aecawb handler
 *    @aec_port:    Pointer to the AEC port - needed to call the event function
 *                  of this port
 *    @aec_cb:      The callback function of the port that will take the output
 *                  from the library and pass it as an event to the port's event
 *                  function.
 *    @aec_obj:     The aec object containing all of the pointer functions to
 *                  communicate with the library. It also contains a pointer to
 *                  the internal library data so that the port's callback may
 *                  process the output data generated by the library.
 *    @awb_port:    Pointer to the AWB port - needed to call the event function
 *                  of this port
 *    @awb_cb:      The callback function of the port that will take the output
 *                  from the library and pass it as an event to the port's event
 *                  function.
 *    @awb_obj:     The awb object containing all of the pointer functions to
 *                  communicate with the library. It also contains a pointer to
 *                  the internal library data so that the port's callback may
 *                  process the output data generated by the library.
 *
 *  This structure is used for containing the data needed by the aecawb thread
 *  handler to operate.
 **/
typedef struct {
  q3a_thread_data_t *thread_data;

  mct_port_t        *aec_port;
  aec_callback_func aec_cb;
  aec_object_t      *aec_obj;

  mct_port_t        *awb_port;
  awb_callback_func awb_cb;
  awb_object_t      *awb_obj;
} q3a_thread_aecawb_data_t;

/** q3a_thread_af_data_t
 *    @thread_data: Contains the thread data associated with the aecawb handler
 *    @af_port:     Pointer to the AF port - needed to call the event function
 *                  of this port
 *    @af_cb:       The callback function of the port that will take the output
 *                  from the library and pass it as an event to the port's event
 *                  function.
 *    @f_obj:       The af object containing all of the pointer functions to
 *                  communicate with the library. It also contains a pointer to
 *                  the internal library data so that the port's callback may
 *                  process the output data generated by the library.
 *
 *  This structure is used for containing the data needed by the af thread
 *  handler to operate.
 **/
typedef struct {
  q3a_thread_data_t *thread_data;

  mct_port_t        *af_port;
  af_callback_func  af_cb;
  af_object_t       *af_obj;
} q3a_thread_af_data_t;

/** q3a_thread_aecawb_msg_type_t
 *
 *  This enumeration represents the types of the messages that the AECAWB
 *  thread handler will recognize and process. SET/GET messages are for
 *  setting and getting parameters, STATS represent event messages from the
 *  ISP that contain stats.
 **/
typedef enum {
  MSG_AEC_SET,
  MSG_AEC_GET,
  MSG_AEC_STATS,
  MSG_BG_AEC_STATS,
  MSG_AEC_STATS_HDR,

  MSG_AWB_SET,
  MSG_AWB_GET,
  MSG_AWB_STATS,
  MSG_BG_AWB_STATS,

  MSG_STOP_THREAD,
  MSG_AEC_SEND_EVENT,
  MSG_AWB_SEND_EVENT,
} q3a_thread_aecawb_msg_type_t;

/** q3a_thread_af_msg_type_t
 *
 *  This enumeration represents the types of the messages that the AF
 *  thread handler will recognize and process. SET/GET messages are for
 *  setting and getting parameters, STATS represent event messages from the
 *  ISP that contain stats, START/CANCEL are command messages from the HAL
 *  to start or stop the focus.
 **/
typedef enum {
  MSG_AF_START,
  MSG_AF_CANCEL,
  MSG_AF_SET,
  MSG_AF_GET,
  MSG_AF_STATS,
  MSG_BF_STATS,
  MSG_AF_STOP_THREAD,
} q3a_thread_af_msg_type_t;

/** msg_sync_t
 *    @msg_sem: semaphore to synchronize the "Sync" messages
 *
 *  This structure is used for creating synchronized messages in the queue.
 *  When such message arrives, the enqueue function will block until the
 *  message is processed by the thread handler and the library returns with
 *  the result.
 **/
typedef struct {
  sem_t  msg_sem;
} msg_sync_t;

/** q3a_thread_aecawb_msg_t
 *    @type:         Indicates the type of the message to be processed by the
 *                   thread.
 *    @sync_flag:    If the message is synced.
 *    @sync_obj:     The sync object to implement the syncing
 *    @is_priority:  A flag indicating if the message is with priority. If yes,
 *                   it will be put into the priority queue.
 *    @stats:        Calculated stats form the ISP.
 *    @aec_set_parm: Used to set a parameter for the AEC.
 *    @aec_get_parm: Used to get a parameter from the AEC.
 *    @awb_set_parm: Used to set a parameter for the AWB.
 *    @awb_get_parm: Used to get a parameter from the AWB.
 *
 *  This structure is used for creating the messages to be put in the queue
 *  of the AECABW thread handler. The messages can be made synchronized (the
 *  caller will block until the message gets processed) as well as prioritized
 *  in order to get processed before all the other messages waiting in the
 *  normal queue.
 **/
typedef struct {
  q3a_thread_aecawb_msg_type_t type;
  boolean         sync_flag;
  msg_sync_t      *sync_obj;
  boolean         is_priority;
  union {
    stats_t *stats;
    aec_set_parameter_t aec_set_parm;
    aec_get_parameter_t aec_get_parm;
    awb_set_parameter_t awb_set_parm;
    awb_get_parameter_t awb_get_parm;
  }u;
} q3a_thread_aecawb_msg_t;

/** q3a_thread_af_msg_t
 *    @type:        Indicates the type of the message to be processed by the
 *                  thread.
 *    @sync_flag:   If the message is synced.
 *    @sync_obj:    The sync object to implement the syncing
 *    @is_priority: A flag indicating if the message is with priority. If yes,
 *                  it will be put into the priority queue.
 *    @stats:       Calculated AF stats form the ISP.
 *    @af_set_parm: Used to set a parameter for the AF.
 *    @af_get_parm: Used to get a parameter from the AF.
 *
 *  This structure is used for creating the messages to be put in the queue
 *  of the AF thread handler. The messages can be prioritized in order to get
 *  processed before all the other messages waiting in the normal queue.
 **/
typedef struct {
  q3a_thread_af_msg_type_t type;
  boolean                  sync_flag;
  msg_sync_t               *sync_obj;
  boolean                  is_priority;
  union {
    stats_af_t         *stats;
    af_set_parameter_t af_set_parm;
    af_get_parameter_t af_get_parm;
  }u;
} q3a_thread_af_msg_t;


q3a_thread_aecawb_data_t* q3a_thread_aecawb_init(void);
void q3a_thread_aecawb_deinit(q3a_thread_aecawb_data_t *data);
boolean q3a_thread_aecawb_start(q3a_thread_aecawb_data_t *aecawb_data);
boolean q3a_thread_aecawb_stop(q3a_thread_aecawb_data_t *aecawb_data);
boolean q3a_aecawb_thread_en_q_msg(void *aecawb_data,
  q3a_thread_aecawb_msg_t  *msg);

q3a_thread_af_data_t* q3a_thread_af_init(void);
void q3a_thread_af_deinit(q3a_thread_af_data_t *data);
boolean q3a_thread_af_start(q3a_thread_af_data_t *af_data);
boolean q3a_thread_af_stop(q3a_thread_af_data_t *af_data);
boolean q3a_af_thread_en_q_msg(void *af_data,
  q3a_thread_af_msg_t  *msg);

#endif /* __Q3A_THREAD_H__ */
